package com.linghui.videoplus.ipai.media;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import com.linghui.videoplus.ipai.VideoPlusApplication;
import com.linghui.videoplus.ipai.activity.BaseActivity;
import com.linghui.videoplus.ipai.activity.VideoSaveActivity;

import android.app.Activity;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaRecorder;
import android.os.Build;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class Recorder implements OnBufferingUpdateListener,
		OnCompletionListener, SurfaceHolder.Callback {

	private Activity mActivity;
	private SurfaceHolder surfaceHolder;
	private MediaRecorder mediaRecorder;
	private Camera mCamera;
	protected boolean isPreview;
	private String url=null;
	int screenOrient=1;
	public Recorder(Activity mActivity, SurfaceView surfaceView) {
		this.mActivity = mActivity;
		surfaceHolder = surfaceView.getHolder();
		surfaceHolder.addCallback(this);
		surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

	}

	/**
	 * 录制
	 */
	public void record(int orient) {
		try {

			if (isPreview) {
				mCamera.stopPreview();
				mCamera.unlock();
			}

			if (mediaRecorder == null) {
				mediaRecorder = new MediaRecorder();
			} else {
				mediaRecorder.reset();
			}
			mediaRecorder.setCamera(mCamera);
			
			this.screenOrient=orient;
			if(screenOrient==2){
				if(VideoPlusApplication.getAndroidSDKVersion()>9){
					mediaRecorder.setOrientationHint(90);
			
				}
			}
			mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
			mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
			mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
			mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
			mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
			if(screenOrient==2&&screenOrient==4){
				mediaRecorder.setVideoSize(480,640);
			}else{
				mediaRecorder.setVideoSize(640,480);
			}
			
			mediaRecorder.setVideoFrameRate(15);
			mediaRecorder.setVideoEncodingBitRate(450*1024);
			mediaRecorder.setMaxDuration(60*1000);
			mediaRecorder.setMaxFileSize(VideoPlusApplication.isAvaiableSpace()*2/3);

			// 设置视频文件输出的路径
			url=getTempVideoPath()+File.separator+System.currentTimeMillis()+".mp4";
			mediaRecorder.setOutputFile(url);
			mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
			mediaRecorder.prepare();
			mediaRecorder.start();
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	
	/**
	 * 取消拍摄
	 */
	public void cancle(){
		mediaRecorder.stop();
		mediaRecorder.release();
		mediaRecorder = null;
		File f=new File(url);
		if(f.exists()){
			f.delete();
		}
	}
	
	/**
	 * 停止录制
	 */
	public synchronized void stop() {
		if (mediaRecorder != null) {
			mediaRecorder.stop();
			mediaRecorder.release();
			mediaRecorder = null;
		}
		String uri=videoRename(url);
		VideoSaveActivity.launch(mActivity, uri,screenOrient,BaseActivity.REQUEST_CODE_CAMERA);
	}

	public void onFlush(){
		Camera.Parameters parameters = mCamera.getParameters();
		parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
		mCamera.setParameters(parameters);
	}
	
	public void offFlush(){
		Camera.Parameters parameters = mCamera.getParameters();
		parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
		mCamera.setParameters(parameters);
	}
	
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		try {
			Camera.Parameters parameters = mCamera.getParameters();
			if (Integer.parseInt(Build.VERSION.SDK) >= 8) {
				if (mActivity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
					setDisplayOrientation(mCamera, 90);    
				}
				
	 
			} else {
				if (mActivity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
					parameters.set("orientation", "portrait");
					parameters.set("rotation", 90);
				}
				if (mActivity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
					parameters.set("orientation", "landscape");
					parameters.set("rotation", 90);
				}
			}
			List<Size> sizes = parameters.getSupportedPreviewSizes();
			Size optimalSize = getOptimalPreviewSize(sizes, width, height);
			parameters.setPreviewSize(optimalSize.width, optimalSize.height);
//			parameters.setPictureSize(optimalSize.width, optimalSize.height);
			parameters.setPreviewFrameRate(15); 
			parameters.setPictureFormat(PixelFormat.JPEG);// 设置照片的输出格式
			parameters.set("jpeg-quality", 85);// 照片质量
			mCamera.setPreviewDisplay(holder);
			mCamera.setParameters(parameters);
			mCamera.startPreview();
			isPreview = true;
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		this.surfaceHolder = holder;
		try {
			if(mCamera==null){
				mCamera = Camera.open();
//				mCamera.setDisplayOrientation(90);
			}
			mCamera.setPreviewDisplay(holder);
		} catch (IOException exception) {
			mCamera.release();
			mCamera = null;

		}
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		if (mCamera != null) {
			mCamera.stopPreview();
			mCamera.release();
			mCamera = null;
		}
	
	}

	@Override
	public void onCompletion(MediaPlayer mp) {

	}

	@Override
	public void onBufferingUpdate(MediaPlayer mp, int percent) {

	}

	private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
		final double ASPECT_TOLERANCE = 0.2;
		double targetRatio = (double) w / h;
		if (sizes == null)
			return null;

		Size optimalSize = null;
		double minDiff = Double.MAX_VALUE;

		int targetHeight = h;

		for (Size size : sizes) {
			double ratio = (double) size.width / size.height;
			if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
				continue;
			if (Math.abs(size.height - targetHeight) < minDiff) {
				optimalSize = size;
				minDiff = Math.abs(size.height - targetHeight);
			}
		}

		if (optimalSize == null) {
			minDiff = Double.MAX_VALUE;
			for (Size size : sizes) {
				if (Math.abs(size.height - targetHeight) < minDiff) {
					optimalSize = size;
					minDiff = Math.abs(size.height - targetHeight);
				}
			}
		}
		return optimalSize;
	}

	protected void setDisplayOrientation(Camera camera, int angle) {
		Method downPolymorphic;
		try {
			downPolymorphic = camera.getClass().getMethod(
					"setDisplayOrientation", new Class[] { int.class });
			if (downPolymorphic != null)
				downPolymorphic.invoke(camera, new Object[] { angle });
		} catch (Exception e1) {
		}
	}
	
	/**
	 * 视频保存目录
	 * @return
	 */
	private String getVideoRoot(){
		File videoPaht = new File(VideoPlusApplication.videoRoot);
		if (!videoPaht.exists()) {
			videoPaht.mkdirs();
		}
		return videoPaht.getPath();
	}
	/**
	 * 视频拍摄临时目录
	 * @return
	 */
	private String getTempVideoPath(){
		File tempVideoPaht = new File(VideoPlusApplication.videoRoot+"temp");
		if (!tempVideoPaht.exists()) {
			tempVideoPaht.mkdirs();
		}
		return tempVideoPaht.getPath();	
		
	}
	/**
	 * 移动
	 * @param srcUri
	 */
	protected String videoRename(String srcUri) {
		String fileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".mp4";
		String filePath=getVideoRoot()+File.separator+fileName;
		File outFile = new File(filePath);
		File srcFile=new File(srcUri);
		if(srcFile.exists()){
			srcFile.renameTo(outFile);
		}
		return filePath;
	}
	
}
